package com.mcxx.modules.minimumliving.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.mcxx.common.exception.BizException;
import com.mcxx.constant.MQConstant;
import com.mcxx.modules.minimumliving.service.FiscalAbutmentService;
import com.mcxx.modules.minimumliving.service.SingleFundPayService;
import com.mcxx.modules.base.service.read.AreaReadService;
import com.mcxx.modules.base.service.read.BankMappingReadService;
import com.mcxx.modules.base.utils.QueryParamUtil;
import com.mcxx.modules.filemanage.easypoi.util.ExportExcelService;
import com.mcxx.modules.filemanage.file.service.FileService;
import com.mcxx.modules.miniSalvation.family.dto.BankAbutmentDTO;
import com.mcxx.modules.miniSalvation.fundpay.dao.read.SingleFundPayReadDao;
import com.mcxx.modules.miniSalvation.fundpay.dto.*;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundPayEntity;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundpayExceptionEntity;
import com.mcxx.modules.miniSalvation.fundpay.param.FundPayFamilyParam;
import com.mcxx.modules.miniSalvation.fundpay.param.FundPayParam;
import com.mcxx.modules.miniSalvation.fundpay.service.read.SingleFundPayExceptionReadService;
import com.mcxx.modules.miniSalvation.fundpay.service.read.SingleFundPayReadService;
import com.mcxx.modules.miniSalvation.fundpay.service.write.SingleFundPayExceptionWriteService;
import com.mcxx.modules.miniSalvation.fundpay.service.write.SingleFundPayWriteService;
import com.mcxx.modules.system.dto.MQMessageDTO;
import com.mcxx.modules.system.entity.TaskExportEntity;
import com.mcxx.modules.system.service.write.TaskExportWriteService;
import com.mcxx.result.BaseResult;
import com.mcxx.util.Constant;
import com.mcxx.util.HttpServiceUtil;
import com.mcxx.util.OkHttpUtil;
import com.yinhai.ta404.component.audit.vo.ExcelInfo;
import com.yinhai.ta404.core.restservice.requestbean.PageParam;
import com.yinhai.ta404.core.restservice.resultbean.Page;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.service.BaseService;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;


@Slf4j
@Service
@TaTransactional
public class SingleFundPayServiceImpl extends BaseService implements SingleFundPayService {
    private static final Logger logger = LoggerFactory.getLogger(SingleFundPayServiceImpl.class);

    @Autowired
    private SingleFundPayReadService singleFundPayReadService;
    @Autowired
    private SingleFundPayWriteService singleFundPayWriteService;
    @Autowired
    private ExportExcelService exportExcelService;
    @Autowired
    private AreaReadService areaReadService;
    @Autowired
    private BankMappingReadService bankMappingReadService;
    @Autowired
    private FiscalAbutmentService fiscalAbutmentService;
    @Autowired
    private SingleFundPayExceptionReadService fundPayExceptionReadService;
    @Autowired
    private SingleFundPayExceptionWriteService fundPayExceptionWriteService;
    @Autowired
    private SingleFundPayReadDao singleFundPayReadDao;
    @Autowired
    private TaskExportWriteService taskExportWriteService;
    @Autowired
    private FileService fileService;
    @Value("${society.fundpay.url:http://10.22.197.53:8011/mc-fundpay/base-info/updateSubsidyObjectAndBankAccountByMqyByTwo}")
    private String fundpayUrl;
    @Value("${society.fundpay.delUrl:http://10.22.197.53:8011/mc-fundpay/base-info/updateSubsidyObjectAndBankAccountByMqyByTwo}")
    private String fundpayDelUrl;



    @Override
    public void saveSingCapitalFundPay(SingleRollDTO params, UserAccountVo userAccountVo) {





        //        params.setStatRollId(rollIds.get(0));

        FundPayEntity capitalRoll = isExistStatRoll(params);

        params.setStatRollId(capitalRoll.getId());

        singleFundPayReadService.isExistTargetFundPay(params);


        singleFundPayWriteService.insertGrantRoll(params, userAccountVo, Constant.FundPayState.CREATE_ING);

    }


    private FundPayEntity isExistStatRoll(SingleRollDTO params) {
        FundPayEntity capitalRoll = singleFundPayReadDao.selectCapitalStatRoll(params);
        if (capitalRoll == null)
            throw new BizException("-1", "对应的统计名册未生成，请先创建对应的统计名册");
        if (!capitalRoll.getStatus().equals(Constant.FundPayState.CONFIRM))
            throw new BizException("-1", "对应的统计名册 未确认 不能创建发放名册，请确认统计名册状态");
        return capitalRoll;
    }



    @Override
    public Map<String, String> gainBankInfo(BankAbutmentDTO dto, UserAccountVo userAccountVo) {
        Map<String, String> map = new HashMap<>();
        if (StringUtils.isEmpty(dto.getSsssidcardnum())) {
            throw new BizException("-1", "身份证号码不能为空");
        }
        if (StringUtils.isEmpty(dto.getSsssobjectname())) {
            throw new BizException("-1", "姓名不能为空");
        }
        if (StringUtils.isEmpty(dto.getBankcode())) {
            throw new BizException("-1", "开户银行不能为空");
        }
        if (StringUtils.isEmpty(dto.getAccouttype())) {
            throw new BizException("-1", "账号类型不能为空");
        }

        if (Constant.FundCapitalType.SOCIAL_SECURITY.equals(dto.getAccouttype())) {
            dto.setAccouttype("0");
        } else {
            dto.setAccouttype("1");
        }



        String tenantIdStr = areaReadService.getTenantIdRela(userAccountVo.getOrgId().substring(0, 6) + "000000");
        dto.setTenantId(tenantIdStr);

        String bankCode = bankMappingReadService.getFinanceByRescue(dto.getBankcode());
        dto.setBankcode(bankCode);
        dto.setDatasources("01");

        log.info("开始获取财政银行卡信息，参数是：{}", dto);







        String result = fiscalAbutmentService.fiscalAbutmentInfo(dto);

        if (!StringUtils.isEmpty(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            String code = jsonObject.getString("code");

            if ("-1".equals(code)) {
                throw new BizException("-1", "当前补贴对象未绑定银行帐号");
            } else {
                String data = jsonObject.getString("data");
                JSONObject jsonData = JSONObject.parseArray(data).getJSONObject(0);
                String accountnum = jsonData.getString("accountnum");
                map.put("accountnum", accountnum);
            }
        }
        return map;
    }



    @Override
    public ExcelInfo exportExcel(String fundpayId) {
        List<FundpayExceptionEntity> list = fundPayExceptionReadService.getExceptionByFundpayId(fundpayId);
        if (null == list || list.size() == 0) {
            return null;
        }
        ExcelInfo excelInfo = exportExcelService.exportOrgOpLogs(FundpayExceptionEntity.class,
                list, "发放名册异常信息表.xls",
                "发放名册异常信息表", "名册对象", false,
                "street", "community", "name", "idcard", "saveNumber", "salaryNumber", "bankName", "bankAccount", "remark");
        return excelInfo;
    }


    @Override
    public void confirmFundPay(String fundPayId, UserAccountVo userAccountVo) {

        List<String> stateList = new ArrayList<String>() {{
            add(Constant.FundPayState.CREATE);
            add(Constant.FundPayState.REVOKE);
        }};
        singleFundPayReadService.isCanOperate(fundPayId, stateList);


        singleFundPayWriteService.confirmFundPay(fundPayId, userAccountVo);
    }


    @Override
    public int verifyNoCompleteNotice(String fundPayId) {
        return singleFundPayReadDao.getNoCompleteOrder(fundPayId);
    }


    @Override
    public BaseResult<Map<String, List<String>>> cancelFundPay(List<String> fundPayIdList) {
        BaseResult<Map<String, List<String>>> result = new BaseResult<>();

        Map<String, List<String>> rstMap = singleFundPayReadService.getIdByIdAndState(fundPayIdList, Constant.FundPayState.CONFIRM);
        if (!rstMap.containsKey("success")) {

            return BaseResult.fail("该名册还未确认");
        }


        for (String fundPayId : fundPayIdList) {
            String retMsg = HttpServiceUtil.httpCallDelFundpayData(fundpayDelUrl, fundPayId);
            if (StringUtils.isNotEmpty(retMsg)) {
                return BaseResult.fail("同步删除发放系统名册失败:" + retMsg);
            }
        }


        int count = fundPayExceptionWriteService.deleteByFundpayId(fundPayIdList);
        logger.info("删除该名册下的所有异常信息，fundPayIds:{}, num:{}", fundPayIdList, count);


        int rst = singleFundPayWriteService.updateStateByIds(rstMap.get("success"), Constant.FundPayState.CREATE, null);


        if (rst <= 0) {

            rstMap.put("fail", fundPayIdList);
            rstMap.remove("success");
        }
        result.setData(rstMap);
        return result;
    }



    @Override
    public Page<FundpayExceptionEntity> getPageFundPayException(String fundPayId, PageParam pageParam) {
        return fundPayExceptionReadService.getPageExceptionByFundpayId(fundPayId, pageParam);
    }


    @Override
    public String checkCanSyncFundPayData(String fundPayId) {
        FundPayEntity fundPayEntity = singleFundPayReadDao.getById(fundPayId);

        if (!Constant.FundPayState.CONFIRM.equals(fundPayEntity.getStatus())) {
            return "该名册还未确认";
        }
        fundPayExceptionWriteService.checkAndConfirmException(fundPayId, null);

        return null;
    }


    @Override
    public String syncFundPayData(String fundPayId) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("fundPayId", fundPayId);
        String retBody = OkHttpUtil.doPost(fundpayUrl, fundPayId);
        if (StringUtils.isNotEmpty(retBody)) {
            retBody = "同步发放名册失败:" + retBody;
        }
        logger.info("同步发放名册结果：{}", retBody);
        return retBody;
    }



    @Override
    public void addFundPayBiz(SingleRollDTO params, UserAccountVo userAccountVo) {

        FundPayEntity capitalRoll = isExistStatRoll(params);

        params.setStatRollId(capitalRoll.getId());

        singleFundPayReadService.isExistTargetFundPay(params);


        params.setId(capitalRoll.getId());
        params.setGrantStandard(capitalRoll.getGrantStandard());
        params.setGrantYears(capitalRoll.getGrantYears());
        params.setPayDate(capitalRoll.getPayDate());
        if (params.getFundType().equals(Constant.FundType.ALLOWANCE_FUND_PAY)) {
            singleFundPayWriteService.insertFundPayAllowanceRoll(params, userAccountVo);
        } else {
            singleFundPayWriteService.insertFundPayRoll(params, userAccountVo);
        }
    }


    @Override
    public ExcelInfo exportFundPayRoll(String exportType, List<String> idsList, FundPayParam param, UserAccountVo curUserAccount) {
        ExcelInfo excelInfo = null;
        QueryParamUtil.setBaseParamValue(param, curUserAccount);
        param.setBusinessType(Constant.BusinessCode.DIBAO);
        if (param.getPayDate() != null) {
            param.setPayDate(param.getPayDate());
        }
        if ("1".equals(exportType)) {

            param.setFundType(Constant.FundType.CAPITAL_FUND_PAY);
            param.setIdsList(idsList);
            List<FundPayExcelDto> list = singleFundPayReadService.exportFundPayList(param);
            excelInfo = exportExcelService.exportOrgOpLogs(FundPayExcelDto.class, list, "资金发放名册信息.xls",
                    "资金发放名册列表", "资金发放名册列表", false, "payDate", "payType", "commitDate",
                    "isAuto", "payWay", "households", "standType");
        } else if ("2".equals(exportType)) {

            param.setFundType(Constant.FundType.STAND_FUND_PAY);
            param.setIdsList(idsList);
            List<FundPayExcelDto> list = singleFundPayReadService.exportFundPayList(param);
            excelInfo = exportExcelService.exportOrgOpLogs(FundPayExcelDto.class, list, "标准补发名册信息.xls",
                    "标准补发名册列表", "标准补发名册列表", false, "replacementType", "replacementMonth",
                    "remark", "payWay", "households", "standType");
        } else if ("3".equals(exportType)) {

            param.setFundType(Constant.FundType.ALLOWANCE_FUND_PAY);
            param.setIdsList(idsList);
            List<FundPayExcelDto> list = singleFundPayReadService.exportFundPayList(param);
            excelInfo = exportExcelService.exportOrgOpLogs(FundPayExcelDto.class, list, "补贴发放名册信息.xls",
                    "补贴发放名册列表", "补贴发放名册列表", false, "itemType", "grantObject", "remark",
                    "grantStandard", "grantYears", "replacementMonth", "remark", "households", "standType");
        }

        return excelInfo;
    }


    @Override
    public ExcelInfo exportFundPayRollDetail(FundPayFamilyParam param, UserAccountVo curUserAccount) {
        ExcelInfo excelInfo = null;
        QueryParamUtil.setBaseParamValue(param, curUserAccount);


//        param.setFundType(Constant.FundType.CAPITAL_FUND_PAY);
        List<FundPayFamilyExcelDTO> list = singleFundPayReadService.exportFundPayRollDetail(param);

        excelInfo = exportExcelService.exportOrgOpLogs(FundPayFamilyExcelDTO.class, list, "发放对象信息.xls",
                "发放对象列表", "发放对象列表", false, null);

        if (null != excelInfo) {
            InputStream sbs = new ByteArrayInputStream(excelInfo.getFile());
            String objectKey = fileService.upload(sbs, excelInfo.getFileName());
            if (StringUtils.isNotBlank(objectKey)) {
                TaskExportEntity taskExport = new TaskExportEntity();
                taskExport.setId(Constant.getUUID());
                taskExport.setUserid(curUserAccount.getUserId());
                taskExport.setTaskName(excelInfo.getFileName());
                taskExport.setTaskTitle("发放对象列表");
                taskExport.setParam("xls");
                taskExport.setCreateTime(new Date());
                taskExport.setFileUrl(objectKey);
                taskExport.setState("02");
                int i = taskExportWriteService.insertIgnoreNull(taskExport);
                if (i > 0) {
                    excelInfo = null;
                }
            }
        }
        return excelInfo;
    }

}
